using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Build.Client;

namespace BuildMonitor.Engine
{
	public class DelcomBuildPublisher : IBuildPublisher
	{
		readonly StringBuilder deviceName = new StringBuilder(DelcomBuildIndicator.MAXDEVICENAMELEN);
		private ConsoleText consoleText;
		public DelcomBuildPublisher(ConsoleText consoleText)
		{
			this.consoleText = consoleText;
		}

		~DelcomBuildPublisher()
		{
			Dispose(false);
		}

		public void Dispose()
		{
			Dispose(true);
		}

		protected void Dispose(bool disposing)
		{
			if (disposing)
			{
				Close();
				GC.SuppressFinalize(this);
			}
		}

		public void Init(List<BuildStoreEvent> events)
		{
			Close(); //ensure the LEDS are all off
			if (events.Count > 0)
			{
				foreach (var buildEvent in events)
				{
					consoleText.WriteLine(string.Format("Build {2} {1}: {0}", buildEvent.Data.Status, buildEvent.Data.LabelName, buildEvent.Data.BuildDefinition.TeamProject));
					if (buildEvent.Data.Status == BuildStatus.Succeeded)
					{
						SetLED(DelcomBuildIndicator.GREENLED, true, false);
					}
					if (buildEvent.Data.Status == BuildStatus.Failed || buildEvent.Data.Status == BuildStatus.Stopped || buildEvent.Data.Status == BuildStatus.PartiallySucceeded)
					{
						SetLED(DelcomBuildIndicator.REDLED, true, false);
					}
				}
			}
		}

		private uint GetDelcomDeviceHandle()
		{
			if (string.IsNullOrEmpty(deviceName.ToString()))
			{
				int Result = 0;
				try
				{
					// Search for the first match USB device, For USB IO Chips use USBIODS
					Result = DelcomBuildIndicator.DelcomGetNthDevice(DelcomBuildIndicator.USBDELVI, 0, deviceName);
				}
				catch (Exception)
				{
					consoleText.WriteLine("Delcom device not found");
				}
				if (Result == 0)
				{
					consoleText.WriteLine("Device not found!\n");
					return 0;
				}
			}

			uint hUSB = DelcomBuildIndicator.DelcomOpenDevice(deviceName, 0); // open the device
			return hUSB;
		}

		public void BuildCompletionEvent(BuildStoreEvent buildStoreEvent)
		{
			var status = buildStoreEvent.Data.Status;
			consoleText.WriteLine(string.Format("[Build Event] {0} : {1} : {2}", buildStoreEvent.Data.Status, buildStoreEvent.Data.BuildDefinition, buildStoreEvent.Data.Quality));
			if (status == BuildStatus.Succeeded)
			{
				SetLED(DelcomBuildIndicator.GREENLED, true, false);
				SetLED(DelcomBuildIndicator.BLUELED, false, false);
				SetLED(DelcomBuildIndicator.REDLED, false, false);
			}
			if (status == BuildStatus.NotStarted || status == BuildStatus.InProgress)
			{
				SetLED(DelcomBuildIndicator.GREENLED, false, false);
				SetLED(DelcomBuildIndicator.BLUELED, true, true);
				SetLED(DelcomBuildIndicator.REDLED, false, false);
			}
			if (status == BuildStatus.PartiallySucceeded)
			{
				SetLED(DelcomBuildIndicator.GREENLED, true, false);
				SetLED(DelcomBuildIndicator.BLUELED, false, false);
				SetLED(DelcomBuildIndicator.REDLED, true, false);
			}
			if (status == BuildStatus.Failed || status == BuildStatus.Stopped)
			{
				SetLED(DelcomBuildIndicator.REDLED, true, false);
				SetLED(DelcomBuildIndicator.GREENLED, false, false);
				SetLED(DelcomBuildIndicator.BLUELED, false, false);
			}
		}

		public void BuildStatusChangeEvent(BuildStoreEvent buildStoreEvent)
		{
			consoleText.WriteLine("[Quality Change Event]");
		}

		public void Close()
		{
			SetLED(DelcomBuildIndicator.GREENLED, false, false);
			SetLED(DelcomBuildIndicator.BLUELED, false, false);
			SetLED(DelcomBuildIndicator.REDLED, false, false);
		}

		private void SetLED(byte led, bool turnItOn, bool flashIt)
		{
			try
			{
				uint hUSB = GetDelcomDeviceHandle(); // open the device
				if (hUSB == 0) return;
				if (turnItOn)
					if (flashIt)
						DelcomBuildIndicator.DelcomLEDControl(hUSB, led, DelcomBuildIndicator.LEDFLASH);
					else
						DelcomBuildIndicator.DelcomLEDControl(hUSB, led, DelcomBuildIndicator.LEDON);
				else
					DelcomBuildIndicator.DelcomLEDControl(hUSB, led, DelcomBuildIndicator.LEDOFF);
				DelcomBuildIndicator.DelcomCloseDevice(hUSB);
			}
			catch (Exception)
			{
				consoleText.WriteLine("Delcom device couldn't be found");
			}
		}
	}
}